// FunctionCall.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <ctime>
#include <iostream>
#include <functional>
#include <map>

__int64 BasicFunctionCall(__int64 n)
{
	// do nothing
	return n;
}

class Base
{
public:
    virtual __int64 FunctionCall(__int64 n) = 0;
};

class Derived : public Base
{
public:
    virtual __int64 FunctionCall(__int64 n);
};

__int64 Derived::FunctionCall(__int64 n)
{
	return n;
}

int main(int argc, _TCHAR* argv[])
{
    __int64 const LoopCount = 10000000000;

    std::cout << "Call count : " << LoopCount << std::endl;

    // Direct call
    {
        auto startTime = time(nullptr);
        for (__int64 i = 0; i < LoopCount; i++)
        {
            BasicFunctionCall(i);
        }
        std::cout << "Direct call Time cost : " << time(nullptr) - startTime << std::endl;
    }

    // Virtual function call
    {
        Base * pCaller = new Derived;
        auto startTime = time(nullptr);
        for (__int64 i = 0; i < LoopCount; i++)
        {
            pCaller->FunctionCall(i);
        }
        std::cout << "Virtual function call Time cost : " << time(nullptr) - startTime << std::endl;
        delete pCaller;
    }

    // std::function call
    {
        std::function<__int64(__int64)> tmpFunc = BasicFunctionCall;
        auto startTime = time(nullptr);
        for (__int64 i = 0; i < LoopCount; i++)
        {
            tmpFunc(i);
        }
        std::cout << "std::function call Time cost : " << time(nullptr) - startTime << std::endl;
    }

	return 0;
}

